package com.huey.utils.qlexpress;

import com.google.common.collect.Lists;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.instruction.op.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author xubo
 * @date 2022/8/23 16:28
 */
public class SecondTest {

    protected boolean isPrecise = false;
    private Map<String, OperatorBase> operator = new HashMap<String, OperatorBase>();

    public static void main(String[] args) throws Exception {
        //111111111111
        ExpressRunner expressRunner = new ExpressRunner();
        DefaultContext<String, Object> context = new DefaultContext<>();
        context.put("mobilePrefix", "162");
        String express = "mobilePrefix in (162,165,167,170,171)";
        Object execute = expressRunner.execute(express, context, null, false, false);
        System.out.println(execute);
        //222222222222
        ExpressRunner expressRunner2 = new ExpressRunner();
        DefaultContext<String, Object> context2 = new DefaultContext<>();
        context2.put("mobilePrefix", "162");
        String express2 = "mobilePrefix in (162,165,167,170,171)";
        //没有合适的设置errorInfo方法 ，无奈用重命名操作符方法来设置errorInfo；errorInfo只针对替换的操作符起作用
        expressRunner.addOperatorWithAlias("等于", "==", "号码不满足期望");
        List<String> errorInfo = new ArrayList<>();
        Object execute2 = expressRunner2.execute(express2, context2, errorInfo, false, false);
        System.out.println(execute2);
        System.out.println(errorInfo.size() > 0 ? errorInfo.get(0) : null);
        //333333333333333333


    }
    public void  OperatorFactory(boolean aIsPrecise){
       // OperatorFactory addOperator1=new OperatorFactory();
        this.isPrecise = aIsPrecise;
        addOperator("new",new OperatorNew("new"));
        addOperator("anonymousNewArray",new OperatorAnonymousNewArray("anonymousNewArray"));
        addOperator("NewList",new OperatorAnonymousNewList("NewList"));
        addOperator(":",new OperatorKeyValue(":"));
        addOperator("NewMap",new OperatorAnonymousNewMap("NewMap"));
        addOperator("def",  new OperatorDef("def"));
        addOperator("exportDef",  new OperatorExportDef("exportDef"));
        addOperator("!",new OperatorNot("!"));
        addOperator("*", new OperatorMultiDiv("*"));
        addOperator("/", new OperatorMultiDiv("/"));
        addOperator("%", new OperatorMultiDiv("%"));
        addOperator("mod", new OperatorMultiDiv("mod"));
        addOperator("+",new OperatorAdd("+"));
        addOperator("-",new OperatorReduce("-"));
        addOperator("<",new OperatorEqualsLessMore("<"));
        addOperator(">",new OperatorEqualsLessMore(">"));
        addOperator("<=",new OperatorEqualsLessMore("<="));
        addOperator(">=",new OperatorEqualsLessMore(">="));
        addOperator("==",new OperatorEqualsLessMore("=="));
        addOperator("!=",new OperatorEqualsLessMore("!="));
        addOperator("<>",new OperatorEqualsLessMore("<>"));
        addOperator("&&",new OperatorAnd("&&"));
        addOperator("||",new OperatorOr("||"));
        addOperator("nor",new OperatorNor("nor"));
        addOperator("=",new OperatorEvaluate("="));
        addOperator("exportAlias",new OperatorExportAlias("exportAlias"));
        addOperator("alias",new OperatorAlias("alias"));
/*        addOperator("break",new OperatorBreak("break"));
        addOperator("continue",new OperatorContinue("continue"));
        addOperator("return",new OperatorReturn("return"));*/
        addOperator("ARRAY_CALL",new OperatorArray("ARRAY_CALL"));
        addOperator("++",new OperatorDoubleAddReduce("++"));
        addOperator("--",new OperatorDoubleAddReduce("--"));
        addOperator("cast", new OperatorCast("cast"));
        addOperator("macro",new OperatorMacro("macro"));
        //addOperator("function",new OperatorFunction("function"));
        addOperator("in", new OperatorIn("in"));
        addOperator("like", new OperatorLike("like"));
        //bit operator
        addOperator("&",new OperatorBit("&"));
        addOperator("|",new OperatorBit("|"));
        addOperator("^",new OperatorBit("^"));
        addOperator("~",new OperatorBit("~"));
        addOperator("<<",new OperatorBit("<<"));
        addOperator(">>",new OperatorBit(">>"));
    }

    public void addOperator(String name, OperatorBase op) {
        OperatorBase oldOp = this.operator.get(name);
        if (oldOp != null) {
            throw new RuntimeException("重复定义操作符：" + name + "定义1："
                    + oldOp.getClass() + " 定义2：" + op.getClass());
        }
        op.setPrecise(this.isPrecise);
        op.setAliasName(name);
        operator.put(name, op);
    }

}
